home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- IsoHex18_2.cpp
- Ernest S. Pazera
- 31AUG2000
- Start a WIN32 Application Workspace, add in this file
- Requires the following libs:
- ddraw.lib, dxguid.lib
- Requires the following files:
- DDFuncs.h.cpp, GDICanvas.h/cpp, IsoMouseMap.h/cpp,
- IsoScroller.h/cpp, IsoTilePlotter.h/cpp, IsoTileWalker.h/cpp
- TileSet.h/cpp. IsoHexCore.h, IsoHexDefs.h
- IsoRenderer.h/cpp
- *****************************************************************************/
-
- //////////////////////////////////////////////////////////////////////////////
- //INCLUDES
- //////////////////////////////////////////////////////////////////////////////
- #define WIN32_LEAN_AND_MEAN
-
- #include <windows.h>
- #include "DDFuncs.h"
- #include "TileSet.h"
- #include "IsoHexCore.h"
- #include "IsoRenderer.h"
-
-
- //////////////////////////////////////////////////////////////////////////////
- //DEFINES
- //////////////////////////////////////////////////////////////////////////////
- //name for our window class
- #define WINDOWCLASS "ISOHEX18"
- //title of the application
- #define WINDOWTITLE "IsoHex 18-2"
-
- const int MAPWIDTH=200;
- const int MAPHEIGHT=400;
-
- //gamestates
- const int GS_IDLE=0;//waits for a keypress
- const int GS_STARTMOVE=1;//sets up the move
- const int GS_DOMOVE=2;//carries out the move
- const int GS_DONEMOVE=3;//finishes the move
-
- //////////////////////////////////////////////////////////////////////////////
- //PROTOTYPES
- //////////////////////////////////////////////////////////////////////////////
- bool Prog_Init();//game data initalizer
- void Prog_Loop();//main game loop
- void Prog_Done();//game clean up
-
- //////////////////////////////////////////////////////////////////////////////
- //GLOBALS
- //////////////////////////////////////////////////////////////////////////////
- HINSTANCE hInstMain=NULL;//main application handle
- HWND hWndMain=NULL;//handle to our main window
-
- //game state
- int iGameState=GS_IDLE;
-
- //directdraw
- LPDIRECTDRAW7 lpdd=NULL;
- LPDIRECTDRAWSURFACE7 lpddsMain=NULL;
- LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
- LPDIRECTDRAWSURFACE7 lpddsFrame=NULL;
-
- //tilesets
- CTileSet tsBack;//background
- CTileSet tsTree;//tree foreground
- CTileSet tsUnit;//unit
-
- //isohexcore components
- CTilePlotter TilePlotter;//plotter
- CTileWalker TileWalker;//walker
- CScroller Scroller;//scroller
- CMouseMap MouseMap;//mousemap
- CRenderer Renderer;//renderer
-
- POINT ptScroll;//keep track of how quickly we scroll
-
- //keep track of unit location
- POINT ptUnit;//current position of the unit
- POINT ptUnitOld;//last position of the unit
- ISODIRECTION idMoveUnit;//direction of movement
- //unit offset
- POINT ptUnitOffset;
- int iUnitFrame=0;
-
- //map location structure
- struct MapLocation
- {
- bool bTree;//false=no tree; true=tree
- bool bUnit;//false=no unit; true=unit;
- };
-
- MapLocation mlMap[MAPWIDTH][MAPHEIGHT];//map array
-
- //rendering functionprototype
- void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap);
-
- //////////////////////////////////////////////////////////////////////////////
- //WINDOWPROC
- //////////////////////////////////////////////////////////////////////////////
- LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
- {
- //which message did we get?
- switch(uMsg)
- {
- case WM_KEYDOWN:
- {
- switch(wParam)
- {
- case VK_ESCAPE:
- {
- DestroyWindow(hWndMain);
- return(0);
- }break;
- case VK_NUMPAD1:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_SOUTHWEST;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD2:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_SOUTH;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD3:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_SOUTHEAST;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD4:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_WEST;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD6:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_EAST;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD7:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_NORTHWEST;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD8:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_NORTH;
- iGameState=GS_STARTMOVE;
- }
- }break;
- case VK_NUMPAD9:
- {
- if(iGameState==GS_IDLE)
- {
- idMoveUnit=ISO_NORTHEAST;
- iGameState=GS_STARTMOVE;
- }
- }break;
- }
- }break;
- case WM_DESTROY://the window is being destroyed
- {
-
- //tell the application we are quitting
- PostQuitMessage(0);
-
- //handled message, so return 0
- return(0);
-
- }break;
- case WM_PAINT://the window needs repainting
- {
- //a variable needed for painting information
- PAINTSTRUCT ps;
-
- //start painting
- HDC hdc=BeginPaint(hwnd,&ps);
-
- /////////////////////////////
- //painting code would go here
- /////////////////////////////
-
- //end painting
- EndPaint(hwnd,&ps);
-
- //handled message, so return 0
- return(0);
- }break;
- }
-
- //pass along any other message to default message handler
- return(DefWindowProc(hwnd,uMsg,wParam,lParam));
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //WINMAIN
- //////////////////////////////////////////////////////////////////////////////
- int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
- {
- //assign instance to global variable
- hInstMain=hInstance;
-
- //create window class
- WNDCLASSEX wcx;
-
- //set the size of the structure
- wcx.cbSize=sizeof(WNDCLASSEX);
-
- //class style
- wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
-
- //window procedure
- wcx.lpfnWndProc=TheWindowProc;
-
- //class extra
- wcx.cbClsExtra=0;
-
- //window extra
- wcx.cbWndExtra=0;
-
- //application handle
- wcx.hInstance=hInstMain;
-
- //icon
- wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
-
- //cursor
- wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
-
- //background color
- wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
-
- //menu
- wcx.lpszMenuName=NULL;
-
- //class name
- wcx.lpszClassName=WINDOWCLASS;
-
- //small icon
- wcx.hIconSm=NULL;
-
- //register the window class, return 0 if not successful
- if(!RegisterClassEx(&wcx)) return(0);
-
- //create main window
- hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
-
- //error check
- if(!hWndMain) return(0);
-
- //if program initialization failed, then return with 0
- if(!Prog_Init()) return(0);
-
- //message structure
- MSG msg;
-
- //message pump
- for(;;)
- {
- //look for a message
- if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- //there is a message
-
- //check that we arent quitting
- if(msg.message==WM_QUIT) break;
-
- //translate message
- TranslateMessage(&msg);
-
- //dispatch message
- DispatchMessage(&msg);
- }
-
- //run main game loop
- Prog_Loop();
- }
-
- //clean up program data
- Prog_Done();
-
- //return the wparam from the WM_QUIT message
- return(msg.wParam);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //INITIALIZATION
- //////////////////////////////////////////////////////////////////////////////
- bool Prog_Init()
- {
- //create IDirectDraw object
- lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
-
- //set display mode
- lpdd->SetDisplayMode(640,480,16,0,0);
-
- //create primary surface
- lpddsMain=LPDDS_CreatePrimary(lpdd,1);
-
- //get back buffer
- lpddsBack=LPDDS_GetSecondary(lpddsMain);
-
- //create the frame buffer
- lpddsFrame=LPDDS_CreateOffscreen(lpdd,640,480);
-
- //load in the mousemap
- MouseMap.Load("MouseMap.bmp");
-
- //set up the tile plotter
- TilePlotter.SetMapType(ISOMAP_DIAMOND);//diamond mode
- TilePlotter.SetTileSize(MouseMap.GetWidth(),MouseMap.GetHeight());//grab width and height from mousemap
-
- //set up tile walker to diamond mode
- TileWalker.SetMapType(ISOMAP_DIAMOND);
-
- //set up screeen space
- RECT rcTemp;
- SetRect(&rcTemp,0,0,640,480);
- Scroller.SetScreenSpace(&rcTemp);
-
- //load in tiles and cursor
- tsBack.Load(lpdd,"backgroundts.bmp");
- tsTree.Load(lpdd,"treets.bmp");
- tsUnit.Load(lpdd,"unit_warrior.bmp");
-
- //grab tile extent from tileset
- CopyRect(&rcTemp,&tsBack.GetTileList()[0].rcDstExt);
-
- //calculate the worldspace
- Scroller.CalcWorldSpace(&TilePlotter,&rcTemp,MAPWIDTH,MAPHEIGHT);
-
- //calculate the mousemap reference point
- MouseMap.CalcReferencePoint(&TilePlotter,&rcTemp);
-
- //calculate anchor space
- Scroller.CalcAnchorSpace();
-
- //set wrap modes for scroller
- Scroller.SetHWrapMode(WRAPMODE_CLIP);
- Scroller.SetVWrapMode(WRAPMODE_CLIP);
-
- //set scroller anchor to (0,0)
- Scroller.GetAnchor()->x=0;
- Scroller.GetAnchor()->y=0;
-
- //attach scrolelr and tilewalker to mousemap
- MouseMap.SetScroller(&Scroller);
- MouseMap.SetTileWalker(&TileWalker);
-
- //set up the map to a random tilefield
- for(int x=0;x<MAPWIDTH;x++)
- {
- for(int y=0;y<MAPHEIGHT;y++)
- {
- mlMap[x][y].bTree=((rand()%2)==1);//random tree
- mlMap[x][y].bUnit=false;//no unit
- }
- }
-
- //calculate the extent rect
- RECT rcExtent;
- CopyRect(&rcExtent,&tsBack.GetTileList()[0].rcDstExt);//set to background extent
- UnionRect(&rcExtent,&rcExtent,&tsTree.GetTileList()[0].rcDstExt);//union with tree extent
- UnionRect(&rcExtent,&rcExtent,&tsUnit.GetTileList()[0].rcDstExt);//union with unit extent
-
- //set up the renderer
- Renderer.SetBackBuffer(lpddsBack);
- Renderer.SetExtentRect(&rcExtent);
- Renderer.SetFrameBuffer(lpddsFrame);
- Renderer.SetMapSize(MAPWIDTH,MAPHEIGHT);
- Renderer.SetMouseMap(&MouseMap);
- Renderer.SetPlotter(&TilePlotter);
- Renderer.SetRenderFunction(RenderFunc);
- Renderer.SetScroller(&Scroller);
- Renderer.SetUpdateRectCount(100);
- Renderer.SetWalker(&TileWalker);
-
- //set the position of the unit
- ptUnit.x=rand()%MAPWIDTH;
- ptUnit.y=rand()%MAPHEIGHT;
- ptUnitOld=ptUnit;//set the old position to the same position
- mlMap[ptUnit.x][ptUnit.y].bUnit=true;//set the unit on the map
-
- //plot the position of the unit
- POINT ptPos=TilePlotter.PlotTile(ptUnit);
-
- ptPos.x-=(Scroller.GetScreenSpaceWidth()/2);//center the unit horizontally
- ptPos.y-=(Scroller.GetScreenSpaceHeight()/2);//center the unit vertically
-
- //set the anchor
- Scroller.SetAnchor(&ptPos);
- Scroller.WrapAnchor();
-
- //update the entire screenspace
- Renderer.AddRect(Scroller.GetScreenSpace());
-
- return(true);//return success
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //CLEANUP
- //////////////////////////////////////////////////////////////////////////////
- void Prog_Done()
- {
- //release frame buffer
- LPDDS_Release(&lpddsFrame);
-
- //release main/back surfaces
- LPDDS_Release(&lpddsMain);
-
- //release directdraw
- LPDD_Release(&lpdd);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //MAIN GAME LOOP
- //////////////////////////////////////////////////////////////////////////////
- void Prog_Loop()
- {
- switch(iGameState)
- {
- case GS_STARTMOVE:
- {
- //remove the unit from the old position
- mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
-
- //calculate new position(virtual new position)
- switch(idMoveUnit)
- {
- case ISO_NORTH:
- case ISO_NORTHEAST:
- case ISO_NORTHWEST:
- case ISO_WEST:
- {
- //move ptUnit
- ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
- //set the offset
- ptUnitOffset.x=0;
- ptUnitOffset.y=0;
- //place unit at old position
- mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=true;
- }break;
- case ISO_EAST:
- {
- //move ptUnit
- ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
- //set the offset
- ptUnitOffset.x=-64;
- ptUnitOffset.y=0;
- //place unit at new position
- mlMap[ptUnit.x][ptUnit.y].bUnit=true;
- }break;
- case ISO_SOUTHEAST:
- {
- //move ptUnit
- ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
- //set the offset
- ptUnitOffset.x=-32;
- ptUnitOffset.y=-16;
- //place unit at new position
- mlMap[ptUnit.x][ptUnit.y].bUnit=true;
- }break;
- case ISO_SOUTHWEST:
- {
- //move ptUnit
- ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
- //set the offset
- ptUnitOffset.x=32;
- ptUnitOffset.y=-16;
- //place unit at new position
- mlMap[ptUnit.x][ptUnit.y].bUnit=true;
- }break;
- case ISO_SOUTH:
- {
- //move ptUnit
- ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
- //set the offset
- ptUnitOffset.x=0;
- ptUnitOffset.y=-32;
- //place unit at new position
- mlMap[ptUnit.x][ptUnit.y].bUnit=true;
- }break;
- }
-
- //set unit frame to 0
- iUnitFrame=0;
-
- //set the next gamestate
- iGameState=GS_DOMOVE;
-
- }break;
- case GS_DONEMOVE:
- {
- //finish the move, make sure the unit is positioned correctly
- switch(idMoveUnit)
- {
- case ISO_NORTH:
- case ISO_NORTHEAST:
- case ISO_NORTHWEST:
- case ISO_WEST:
- {
- //remove from old position
- mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
- //place on new position
- mlMap[ptUnit.x][ptUnit.y].bUnit=true;
- }break;
- }
-
- //plot new tile's position
- POINT ptPlot=TilePlotter.PlotTile(ptUnit);
- ptPlot=Scroller.WorldToScreen(ptPlot);
-
- //set scrolling to 0,0
- ptScroll.x=0;
- ptScroll.y=0;
-
- //check for scrolling
- if(ptPlot.x<0) ptScroll.x=-320;
- if(ptPlot.y<0) ptScroll.y=-240;
- if(ptPlot.x>=640) ptScroll.x=320;
- if(ptPlot.y>=480) ptScroll.y=240;
-
- //scroll the frame
- Renderer.ScrollFrame(ptScroll.x,ptScroll.y);
-
- //add update tiles
- Renderer.AddTile(ptUnitOld.x,ptUnitOld.y);
- Renderer.AddTile(ptUnit.x,ptUnit.y);
-
- //set ptUnitOffset to (0,0)
- ptUnitOffset.x=0;
- ptUnitOffset.y=0;
- //set the old unit position to the current unit position
- ptUnitOld=ptUnit;
- //go to idling gamestate
- iGameState=GS_IDLE;
-
- //update the frame
- Renderer.UpdateFrame();
-
- //flip
- lpddsMain->Flip(0,DDFLIP_WAIT);
- }break;
- case GS_DOMOVE:
- {
- //move the unit offset
- switch(idMoveUnit)
- {
- case ISO_NORTH:
- {
- //change offset
- ptUnitOffset.x+=0;
- ptUnitOffset.y-=8;
- }break;
- case ISO_NORTHEAST:
- {
- //change offset
- ptUnitOffset.x+=8;
- ptUnitOffset.y-=4;
- }break;
- case ISO_EAST:
- {
- //change offset
- ptUnitOffset.x+=16;
- ptUnitOffset.y+=0;
- }break;
- case ISO_SOUTHEAST:
- {
- //change offset
- ptUnitOffset.x+=8;
- ptUnitOffset.y+=4;
- }break;
- case ISO_SOUTH:
- {
- //change offset
- ptUnitOffset.x+=0;
- ptUnitOffset.y+=8;
- }break;
- case ISO_SOUTHWEST:
- {
- //change offset
- ptUnitOffset.x-=8;
- ptUnitOffset.y+=4;
- }break;
- case ISO_WEST:
- {
- //change offset
- ptUnitOffset.x-=16;
- ptUnitOffset.y+=0;
- }break;
- case ISO_NORTHWEST:
- {
- //change offset
- ptUnitOffset.x-=8;
- ptUnitOffset.y-=4;
- }break;
- }
-
- //grab the update RECTs
- RECT rcUpdate1,rcUpdate2;
- CopyRect(&rcUpdate1,&Renderer.rcExtent);
- CopyRect(&rcUpdate2,&Renderer.rcExtent);
-
- //plot the position of the units old position
- POINT ptPlot=TilePlotter.PlotTile(ptUnitOld);
- ptPlot=Scroller.WorldToScreen(ptPlot);
- OffsetRect(&rcUpdate1,ptPlot.x,ptPlot.y);
-
- //plot the position of the unit's new position
- ptPlot=TilePlotter.PlotTile(ptUnit);
- ptPlot=Scroller.WorldToScreen(ptPlot);
- OffsetRect(&rcUpdate2,ptPlot.x,ptPlot.y);
-
- //scroll the frame (0,0)
- Renderer.ScrollFrame(0,0);
-
- //merge the two update RECTS
- UnionRect(&rcUpdate1,&rcUpdate1,&rcUpdate2);
-
- //send update rect to the renderer
- Renderer.AddRect(&rcUpdate1);
-
- //update the frame
- Renderer.UpdateFrame();
-
- //flip to show the back buffer
- lpddsMain->Flip(0,DDFLIP_WAIT);
-
- //increase the unit frame counter
- iUnitFrame++;
-
- //check for done with gamestate
- if(iUnitFrame==4)
- {
- //set to the next gamestate
- iGameState=GS_DONEMOVE;
- }
-
- }break;
- case GS_IDLE://the game is idling, update the frame, but thats about it.
- {
- //scroll the frame (0,0)
- Renderer.ScrollFrame(0,0);
- //update the frame
- Renderer.UpdateFrame();
- //flip to show the back buffer
- lpddsMain->Flip(0,DDFLIP_WAIT);
- }break;
- }
- }
-
- void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap)
- {
- //put background tile
- tsBack.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
- //check for a tree
- if(mlMap[xMap][yMap].bTree)
- {
- //put tree
- tsTree.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
- }
- //check for the unit
- if(mlMap[xMap][yMap].bUnit)
- {
- //put unit
- tsUnit.ClipTile(lpddsDst,rcClip,xDst+ptUnitOffset.x,yDst+ptUnitOffset.y,0);
- }
- }
-